//
// @Auther: by wujehy 
// @Email:wujehy@qq.com
// @Data:20-5-7
// @Time:下午1:55
//
/**
 * @brief 测试用例
 * @author WuJeHy
 * @file test_protocol.cpp
 */

#include <gtest/gtest.h>
#include "GeeJoan.h"
#include <iostream>

void initTest()
{
    // 初始化的动作
}

void deinitTest()
{
    // 反初始化
}

#define RESET   "\033[0m"
#define RED     "\033[31m"      /* Red */
#define GREEN   "\033[32m"      /* Green */
#define YELLOW  "\033[33m"      /* Yellow */
#define BLUE    "\033[34m"      /* Blue */

void printBuff(char *data, int len)
{
    printf("%s", YELLOW);
    for (int i = 0; i < len; ++i)
    {
        printf("%02X", data[i]&0xff);
    }
    {
        printf("%s", RESET);
    }
}


TEST(PROTOCOL, NetWorkRequest)
{
    std::cout << YELLOW << "Test NetWorkRequest  " << RESET << std::endl;
    // // NOTE 需要序列化 数据
    // Auth mod
    NetWorkPackageModel mod = NetWorkPackageModel_IOTMod;
    int sub_type = AUTH_LOGIN;
    long long taskid = 1;
    std::string body = "test body";
    std::string publicKey = "testkey";

    // 序列化 的字节流
    void *buffer = 0;

    // 引用传递 buff  和补充参数
    int len = serialzeNetWorkPackageRequest(&buffer,
            mod ,sub_type ,
            taskid , (void*)body.c_str() , body.length() , (void*)publicKey.c_str() , publicKey.length());

    // 打印
    printf("serial buffer: ");
    printBuff((char *) buffer, len);
    printf("\n");
    // 反序列化
    NetWorkPackageRequest *request;
    ERRORCODE ret = deserialzeNetWorkPackageRequest(&request, buffer, len);
    // 成功 , 判断是否
    EXPECT_EQ(ret, ERROR_OK);


    std::cout << "deserialze registerApi : " << GREEN << "PASS" << RESET << std::endl;
    // 判断 解密 后的 数据 和 原数据 是否 相同

    EXPECT_EQ(mod , request->type_m);
    std::cout << "          mod deserial : " << GREEN << "PASS" << RESET << std::endl;

    EXPECT_EQ(sub_type , request->type_sub);
    std::cout << "     sub_type deserial : " << GREEN << "PASS" << RESET << std::endl;


    EXPECT_EQ(taskid , request->taskid);
    std::cout << "       taskid deserial : " << GREEN << "PASS" << RESET << std::endl;

    EXPECT_EQ(memcmp(body.c_str(), request->body.data , body.length()), 0);
    std::cout << "         body deserial : " << GREEN << "PASS" << RESET << std::endl;

    EXPECT_EQ(memcmp(publicKey.c_str(), request->pubilckey.data, publicKey.length()), 0);
    std::cout << "    publicKey deserial : " << GREEN << "PASS" << RESET << std::endl;


    free(buffer); // 释放内存
    free_NetWorkPackageRequest(request); // 释放内存
    return;
}




TEST(PROTOCOL, NetWorkRespse)
{
    std::cout << YELLOW << "Test NetWorkRespse  " << RESET << std::endl;
    // // NOTE 需要序列化 数据
    // Auth mod
    NetWorkPackageModel mod = NetWorkPackageModel_IOTMod;

    int sub_type = AUTH_LOGIN;
    long long taskid = 1;
    int code = 200 ;
    std::string body = "test body";
    std::string publicKey = "testkey";

    // 序列化 的字节流
    void *buffer = 0;

    // 引用传递 buff  和补充参数
    int len = serialzeNetWorkPackageRespose(&buffer,
                                            mod ,sub_type ,
                                            taskid , code, (void*)body.c_str() , body.length() , (void*)publicKey.c_str() , publicKey.length());

    // 打印
    printf("serial buffer: ");
    printBuff((char *) buffer, len);
    printf("\n");
    // 反序列化
    NetWorkPackageRespose *respose;
    ERRORCODE ret = deserialzeNetWorkPackageRespose(&respose, buffer, len);
    // 成功 , 判断是否
    EXPECT_EQ(ret, ERROR_OK);


    std::cout << "deserialze registerApi : " << GREEN << "PASS" << RESET << std::endl;
    // 判断 解密 后的 数据 和 原数据 是否 相同

    EXPECT_EQ(mod , respose->type_m);
    std::cout << "          mod deserial : " << GREEN << "PASS" << RESET << std::endl;

    EXPECT_EQ(sub_type , respose->type_sub);
    std::cout << "     sub_type deserial : " << GREEN << "PASS" << RESET << std::endl;


    EXPECT_EQ(taskid , respose->taskid);
    std::cout << "       taskid deserial : " << GREEN << "PASS" << RESET << std::endl;


    EXPECT_EQ(code , respose->code);
    std::cout << "         code deserial : " << GREEN << "PASS" << RESET << std::endl;


    EXPECT_EQ(memcmp(body.c_str(), respose->body.data , body.length()), 0);
    std::cout << "         body deserial : " << GREEN << "PASS" << RESET << std::endl;

    free(buffer); // 释放内存
    free_NetWorkPackageRespose(respose); // 释放内存
    return;
}


TEST(PROTOCOL, registerApi)
{
    std::cout << YELLOW << "Test registerApi  " << RESET << std::endl;
    // NOTE 需要序列化 数据

    std::string username = "testusername";
    std::string password = "testpassword";
    std::string email = "testemail";

    // 序列化 的字节流
    void *buffer = 0;

    // 引用传递 buff  和补充参数
    int len = serialzeRegisterAPI(&buffer, username.c_str() , password.c_str(), email.c_str());
    // 打印
    printf("serial buffer: ");
    printBuff((char *) buffer, len);
    printf("\n");
    // 反序列化
    RegisterAPI *registerApi;
    ERRORCODE ret = deserialzeRegisterAPI(&registerApi, buffer, len);
    // 成功 , 判断是否
    EXPECT_EQ(ret, ERROR_OK);
    std::cout << "deserialze registerApi : " << GREEN << "PASS" << RESET << std::endl;
    // 判断 解密 后的 数据 和 原数据 是否 相同
    EXPECT_EQ(memcmp(username.c_str(), registerApi->username, username.length()), 0);
    std::cout << "     username deserial : " << GREEN << "PASS" << RESET << std::endl;

    EXPECT_EQ(memcmp(password.c_str(), registerApi->password, password.length()), 0);
    std::cout << "     password deserial : " << GREEN << "PASS" << RESET << std::endl;

    EXPECT_EQ(memcmp(email.c_str(), registerApi->email, email.length()), 0);
    std::cout << "        email deserial : " << GREEN << "PASS" << RESET << std::endl;


    free(buffer); // 释放内存
    free_RegisterAPI(registerApi); // 释放内存
    return;
}

TEST(PROTOCOL, loginRequest)
{

    std::cout << YELLOW << "Test loginRequest  " << RESET << std::endl;

    // NOTE 需要序列化 数据
    std::string username = "testusername";
    std::string password = "testpassword";
    int64_t timestamp = 123456;

    // 序列化 的字节流
    void *buffer = 0;
    // 引用传递 buff  和补充参数
    int len = serialzeLoginRequest(&buffer, username.c_str(), password.c_str(), 123456);

    // 打印

    printf("serial buffer: ");
    printBuff((char *) buffer, len);
    printf("\n");
    // 反序列化
    LoginRequest *loginRequest;
    ERRORCODE ret = deserialzeLoginRequest(&loginRequest, buffer, len);

    // 成功 , 判断是否 解包成功
    EXPECT_EQ (ret, ERROR_OK);

    // 输入 数据
    std::cout << "deserialzeLoginRequest : " << GREEN << "PASS" << RESET << std::endl;

    // 判断 解密 后的 数据 和 原数据 是否 相同
    std::cout;
    EXPECT_EQ(memcmp(username.c_str(), loginRequest->username, username.length()), 0);
    std::cout << "     usernaem deserial : " << GREEN << "PASS" << RESET << std::endl;


    EXPECT_EQ (memcmp(password.c_str(), loginRequest->password, username.length()), 0);
    std::cout << "     password deserial : " << GREEN << "PASS" << RESET << std::endl;


    EXPECT_EQ (timestamp, loginRequest->timestamp);
    std::cout << "    timestamp deserial : " << GREEN << "PASS" << RESET << std::endl;


    free(buffer); // 释放内存
    free_LoginRequest(loginRequest); // 释放内存
    return;
}


TEST(PROTOCOL, loginRespose)
{
    std::cout << YELLOW << "Test loginRespose  " << RESET << std::endl;
    // NOTE 需要序列化 数据
    std::string token = "testtoken";
    // 序列化 的字节流
    void *buffer = 0;
    // 引用传递 buff  和补充参数
    int len = serialzeLoginRespose(&buffer, token.c_str());
    // 打印
    printf("serial buffer: ");
    printBuff((char *) buffer, len);
    printf("\n");
    // 反序列化
    LoginRespose *loginRespose;
    ERRORCODE ret = deserialzeLoginRespose(&loginRespose, buffer, len);
    // 成功 , 判断是否
    EXPECT_EQ(ret, ERROR_OK);
    std::cout << "deserialzeLoginRequest : " << GREEN << "PASS" << RESET << std::endl;
    // 判断 解密 后的 数据 和 原数据 是否 相同
    EXPECT_EQ(memcmp(token.c_str(), loginRespose->token, token.length()), 0);
    std::cout << "        token deserial : " << GREEN << "PASS" << RESET << std::endl;

    free(buffer); // 释放内存
    free_LoginRespose(loginRespose); // 释放内存
    return;
}



TEST(PROTOCOL, logoutAPI)
{
    std::cout << YELLOW << "Test logoutAPI  " << RESET << std::endl;
    // NOTE 需要序列化 数据
    std::string token = "testtoken";
    int64_t timestamp = 123456;
    // 序列化 的字节流
    void *buffer = 0;

    // 引用传递 buff  和补充参数
    int len = serialzeLogoutAPI(&buffer, token.c_str() , timestamp);
    // 打印
    printf("serial buffer: ");
    printBuff((char *) buffer, len);
    printf("\n");
    // 反序列化
    LogoutAPI *logoutApi;
    ERRORCODE ret = deserialzeLogoutAPI(&logoutApi, buffer, len);
    // 成功 , 判断是否
    EXPECT_EQ(ret, ERROR_OK);
    std::cout << "deserialze logoutAPI : " << GREEN << "PASS" << RESET << std::endl;
    // 判断 解密 后的 数据 和 原数据 是否 相同
    EXPECT_EQ(memcmp(token.c_str(), logoutApi->token, token.length()), 0);
    std::cout << "      token deserial : " << GREEN << "PASS" << RESET << std::endl;

    EXPECT_EQ(timestamp , logoutApi->timestamp);
    std::cout << "  timestamp deserial : " << GREEN << "PASS" << RESET << std::endl;

    free(buffer); // 释放内存
    free_LogoutAPI(logoutApi); // 释放内存
    return;
}




TEST(PROTOCOL, ChangePasswordRequest)
{
    std::cout << YELLOW << "Test ChangePasswordRequest  " << RESET << std::endl;
    // NOTE 需要序列化 数据
    std::string oldtoken = "testtoken";
    std::string newpassword = "testpassword";
    int64_t timestamp = 123456;
    // 序列化 的字节流
    void *buffer = 0;

    // 引用传递 buff  和补充参数
    int len = serialzeChangePasswordRequest(&buffer, oldtoken.c_str() , newpassword.c_str() , timestamp);
    // 打印
    printf("serial buffer: ");
    printBuff((char *) buffer, len);
    printf("\n");
    // 反序列化
    ChangePasswordRequest *req;
    ERRORCODE ret = deserialzeChangePasswordRequest(&req, buffer, len);
    // 成功 , 判断是否
    EXPECT_EQ(ret, ERROR_OK);
    std::cout << "deserialze ChangePasswordRequest : " << GREEN << "PASS" << RESET << std::endl;
    // 判断 解密 后的 数据 和 原数据 是否 相同
    EXPECT_EQ(memcmp(oldtoken.c_str(), req->oldtoken, oldtoken.length()), 0);
    std::cout << "               oldtoken deserial : " << GREEN << "PASS" << RESET << std::endl;

    EXPECT_EQ(memcmp(newpassword.c_str(), req->newpassword, newpassword.length()), 0);
    std::cout << "            newpassword deserial : " << GREEN << "PASS" << RESET << std::endl;

    EXPECT_EQ(timestamp , req->timestamp);
    std::cout << "              timestamp deserial : " << GREEN << "PASS" << RESET << std::endl;

    free(buffer); // 释放内存
    free_ChangePasswordRequest(req); // 释放内存
    return;
}

TEST(PROTOCOL , FindSensorDataRespose)
{
    std::cout << YELLOW << "Test FindSensorDataRespose  " << RESET << std::endl;
    // 初始化 数据包
    int package_size = 3 ;
    SensorDataPackage dataPackages[package_size];
    initSensorDataPackages(dataPackages , package_size);

    // 填充数据
    char *test_data="testdata";
    int64_t testTimestamp = 1234567890123;
    for (int i = 0; i < package_size; ++i)
    {
        dataPackages[i].time=testTimestamp;
        dataPackages[i].key=i;
        dataPackages[i].data.data=(uint8_t *)test_data;
        dataPackages[i].data.len= sizeof(test_data);
    }

    uint64_t gatewayid = 1;
    uint64_t deviceid = 1;

    // 序列化
    void* buff = 0 ;
    int  len = serialzeFindSensorDataRespose( &buff , gatewayid , deviceid , dataPackages , package_size);

    printf("serial buffer: ");
    printBuff((char *) buff, len);
    printf("\n");

    // 反序列化
    FindSensorDataRespose *respose;
    ERRORCODE ret = deserialzeFindSensorDataRespose(&respose , buff , len);
    // 成功
    EXPECT_EQ(ret, ERROR_OK);
    std::cout << "deserialze FindSensorDataRespose : " << GREEN << "PASS" << RESET << std::endl;

    EXPECT_EQ(gatewayid , respose->gatewayid);
    std::cout << "              gatewayid deserial : " << GREEN << "PASS" << RESET << std::endl;
    EXPECT_EQ(deviceid , respose->deviceid);
    std::cout << "               deviceid deserial : " << GREEN << "PASS" << RESET << std::endl;
    EXPECT_EQ(gatewayid , respose->gatewayid);
    std::cout << "              gatewayid deserial : " << GREEN << "PASS" << RESET << std::endl;

    EXPECT_EQ(package_size , respose->n_datas);
    std::cout << "                n_datas deserial : " << GREEN << "PASS" << RESET << std::endl;

    for (int j = 0; j < package_size; ++j)
    {

        EXPECT_EQ(j , respose->datas[j]->key);
        EXPECT_EQ(testTimestamp , respose->datas[j]->time);
        EXPECT_EQ(memcmp(test_data , respose->datas[j]->data.data , respose->datas[j]->data.len) , 0 );
        std::cout << "               index deserial["<<j<<"] : " << GREEN << "PASS" << RESET << std::endl;

    }
    
    free_FindSensorDataRespose(respose);
    free(buff);
}

GTEST_API_ int main(int argc, char **argv)
{

    testing::InitGoogleTest(&argc, argv);
    initTest();
    int ret = RUN_ALL_TESTS();
    deinitTest();
    return ret;
}
